package com.esun.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.esun.common.constant.Constants;
import com.esun.common.constant.HttpStatus;
import com.esun.payment_api.security.model.LoginUser;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

public class JWTUtils {
    /**
     * 签名加密算法需要的盐
     */
    private static final String SING = "esfa@ESUN";
    /**
     * token有效时常，分钟
     * 2023-12-25 改为7天
     */
    private static final int EXPIRE_TIME = 60*24*7;
    //private static final int EXPIRE_TIME = 30;
    /**
     * 生成token
     */
    public static String createToken(Map<String, String> payload){
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.MINUTE, EXPIRE_TIME); //默认30分钟过期

        JWTCreator.Builder builder = JWT.create();
        payload.forEach((k,v)->{
            builder.withClaim(k, v);
        });

        builder.withExpiresAt(instance.getTime());
        String token = builder.sign(Algorithm.HMAC256(SING));

        return token;
    }

    /**
     * 验证token
     */
    public static void verify(String token){
        try {
            JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
        } catch (Exception e) {
            System.out.println("验证中：token为空");
        }
    }
    /**
     * 获取token中的信息
     */
    public static DecodedJWT getTokenInfo(String token){
        DecodedJWT verify = JWT.require(Algorithm.HMAC256(SING)).build().verify(token);
        return verify;
    }

    /**
     * 获取请求中的token
     *
     * @param request
     * @return token
     */
    public static String getToken(HttpServletRequest request)
    {
        String token = request.getHeader(Constants.TOKEN_HEADER);
        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX))
        {
            token = token.replace(Constants.TOKEN_PREFIX, "");
        }else{
            token = null;
        }
        return token;
    }

    /**
     * 判断令牌是否过期
     *
     * @param token 令牌
     * @return 是否过期
     */
    public static Boolean isTokenExpired(String token) {
        try {
            DecodedJWT tokenInfo = getTokenInfo(token);
            Date expiration = tokenInfo.getExpiresAt();
            return expiration.before(new Date());
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取登录请求用户身份信息
     *
     * @return 用户信息
     */
    public static LoginUser getLoginUser(HttpServletRequest request)
    {
        // 获取请求携带的令牌
        String token = getToken(request);
        if (StringUtils.isNotEmpty(token))
        {
            DecodedJWT tokenInfo = getTokenInfo(token);
            Date expiration = tokenInfo.getExpiresAt();
            if(expiration.before(new Date())){
                return null;
            }else {

                LoginUser user = new LoginUser();
                user.setId(Short.parseShort(tokenInfo.getClaim("id").asString()));
                user.setLoginName(tokenInfo.getClaim("loginName").asString());
                user.setUserName(tokenInfo.getClaim("userName").asString());
                user.setUuid(tokenInfo.getClaim("uuid").asString());
                if(tokenInfo.getClaim("coId")!=null){
                    user.setCoId(Short.parseShort(tokenInfo.getClaim("coId").asString()));
                }
                if(tokenInfo.getClaim("deptId")!=null){
                    user.setDeptId(Short.parseShort(tokenInfo.getClaim("deptId").asString()));
                }
                if(tokenInfo.getClaim("departmentName")!=null){
                    System.out.println(tokenInfo.getClaim("departmentName").asString());
                    user.setDepartmentName(tokenInfo.getClaim("departmentName").asString());
                }

                return user;
            }
        }
        return null;
    }

    /**
     * 获取鉴权后上下文中的用户信息
     **/
    public static LoginUser getLoginUser()
    {
        try
        {
            return (LoginUser) getAuthentication().getPrincipal();
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    /**
     * 获取Authentication
     */
    public static Authentication getAuthentication()
    {
        return SecurityContextHolder.getContext().getAuthentication();
    }
}
